﻿//*********************************//
//base on jQuery 1.4.1
//Nov 30, 2012
//*********************************//
(function($){	
    function SingleCalendar(options) {
        this.option = {
            text_obj: "",
            minYear: 1990,
            extend_year: 10,
            split: "-",
            bg: "#000",
            year_month_bg: "#282828",
            year_month_color: "#f38200",
            foot_today: "#f38200",
            current_month_date: "#f38200",
            title_days: "#afafaf",
            not_current_month_date: "#afafaf",
            selectedbg: "#f38200",
            selectedColor: "#000",
            hoverColor: "#000",
            hoverbg: "#afafaf",
            titleDisabledColor: "#afafaf",
            onselected: function () { }
        }
        for (var item in options) {
            this.option[item] = options[item];
        }
        var opt = this.option;
        this.obj = $("#" + opt.text_obj).attr({ "readOnly": true, "autoComplete": false });
        if (this.obj.length) var obj = this.obj;
        else {
            alert("ID为" + opt.text_obj + "的对象不存在！");
            return false;
        }

        function creatCalendar(year, month) {
            if ($("#calendar_single").length)
                $("#calendar_single").remove();
            var today = new Date();
            var thisYear = today.getFullYear();
            var thisMonth = today.getMonth();
            var thisDate = today.getDate();

            year = !year ? (obj.val().length ? obj.val().split('-')[0] * 1 : thisYear) : year;
            month = !month ? (obj.val().length ? obj.val().split('-')[1] * 1 : thisMonth + 1) : month;
            date = obj.val().length ? obj.val().split('-')[2] * 1 : thisDate;
            if (year < opt.minYear) opt.minYear = year;

            var _div = $("<div>")
            .attr({ "id": "calendar_single" })
            .css({
                "border": "2px solid #646464", "display": "none", "width": 190, "*width": 194, "position": "absolute",
                "z-index": 10000, "background": opt.bg
            })
            .click(function (e) { stopBubble(e); })
            .append($("<div>")
                    .css({ "height": 26, "background": opt.year_month_bg })
                    .append($("<div>").attr("id", "singleCalendarLastYear")
                            .html("&lt;&lt;")
                            .css({ "width": 18, "line-height": "26px", "float": "left", "text-align": "center", "font-size": 12, "color": opt.year_month_color })
                            .hover(
                                function () {
                                    if (isDisabled(this)) return false;
                                    $(this).css({ "background": opt.hoverbg, "color": opt.hoverColor, "cursor": "pointer" });
                                },
                                function () {
                                    if (isDisabled(this)) return false;
                                    $(this).css({ "background": opt.year_month_bg, "color": opt.year_month_color, "cursor": "normal" });
                                })
                            .click(function () {
                                if (!isDisabled(this)) {
                                    creatCalendar(selects.eq(0).val() * 1 - 1, selects.eq(1).val() * 1);
                                    $("#calendar_single").show();
                                }
                                return false;
                            }))
                    .append($("<div>")
                            .html("&lt;").attr("id", "singleCalendarLastMonth")
                            .css({ "width": 15, "line-height": "26px", "float": "left", "text-align": "center", "font-size": 12, "color": opt.year_month_color })
                            .hover(
                                function () {
                                    if (isDisabled(this)) return false;
                                    $(this).css({ "background": opt.hoverbg, "color": opt.hoverColor, "cursor": "pointer" });
                                },
                                function () {
                                    if (isDisabled(this)) return false;
                                    $(this).css({ "background": opt.year_month_bg, "color": opt.year_month_color, "cursor": "normal" });
                                })
                            .click(function () {
                                if (!isDisabled(this)) {
                                    (selects.eq(1).val() * 1 - 1 < 1) ?
                                    creatCalendar(selects.eq(0).val() * 1 - 1, 12) :
                                    creatCalendar(selects.eq(0).val() * 1, selects.eq(1).val() * 1 - 1);
                                    $("#calendar_single").show();
                                }
                                return false;
                            }))
                    .append($("<select>").css({ "float": "left", "margin-top": 3, "width": 68 }))
                    .append($("<select>").css({ "float": "left", "margin": "3px 0 0 3px", "width": 53 }))
                    .append($("<div>")
                            .html("&gt;").attr("id", "singleCalendarNextMonth")
                            .css({ "width": 15, "line-height": "26px", "float": "left", "text-align": "center", "font-size": 12, "color": opt.year_month_color })
                            .hover(
                                function () {
                                    if (isDisabled(this)) return false;
                                    $(this).css({ "background": opt.hoverbg, "color": opt.hoverColor, "cursor": "pointer" });
                                },
                                function () {
                                    if (isDisabled(this)) return false;
                                    $(this).css({ "background": opt.year_month_bg, "color": opt.year_month_color, "cursor": "normal" });
                                })
                            .click(function () {
                                if (!isDisabled(this)) {
                                    selects.eq(1).val() == 12 ?
                                    creatCalendar(selects.eq(0).val() * 1 + 1, 1) :
                                    creatCalendar(selects.eq(0).val() * 1, selects.eq(1).val() * 1 + 1);
                                    $("#calendar_single").show();
                                }
                                return false;
                            }))
                    .append($("<div>")
                            .html("&gt;&gt;").attr("id", "singleCalendarNextYear")
                            .css({ "width": 18, "line-height": "26px", "float": "left", "text-align": "center", "font-size": 12, "color": opt.year_month_color })
                            .hover(
                                function () {
                                    if (isDisabled(this)) return false;
                                    $(this).css({ "background": opt.hoverbg, "color": opt.hoverColor, "cursor": "pointer" });
                                },
                                function () {
                                    if (isDisabled(this)) return false;
                                    $(this).css({ "background": opt.year_month_bg, "color": opt.year_month_color, "cursor": "normal" });
                                })
                            .click(function () {
                                if (!isDisabled(this)) {
                                    creatCalendar(selects.eq(0).val() * 1 + 1, selects.eq(1).val() * 1);
                                    $("#calendar_single").show();
                                }
                                return false;
                            })))
            .append($("<div>")
                    .attr("id", "singleCalendarTitleDays")
                    .css({ "width": 184, "*width": 179, "margin-left": 6, "*margin-left": 8, "height": 22, "font-family": "宋体", "font-size": 12, "color": opt.title_days })
                )
            .append($("<div>")
                    .attr("id", "singleCalendarBody")
                    .css({ "width": 170, "*width": 168, "margin-left": 9, "*margin-left": 10, "border-top": "1px solid #717171", "border-bottom": "1px solid #717171" })
                )
            .append($("<div>")
                    .css({ "font-family": "Airal", "font-size": 12, "color": opt.foot_today, "width": 184, "*width": 179, "margin-left": 10, "line-height": "26px" })
                    .text("今天：" + thisYear + "/" + (thisMonth + 1) + "/" + thisDate)
                )
            .appendTo($("body"));
            var _titleDays = $("#singleCalendarTitleDays");
            for (var i in SingleCalendar.prototype.days) {
                _titleDays.append(
                    $("<div>").css({ "width": 25, "text-align": "center", "float": "left", "line-height": "22px" })
                    .text(SingleCalendar.prototype.days[i]));
            }

            var pre_month = new Date(year, month - 1, 0);
            var this_month = new Date(year, month, 0);
            var next_month = new Date(year, month + 1, 0);
            var firstDay = new Date(year, month - 1, 1).getDay();
            var _table = $("<table>").appendTo($("#singleCalendarBody"));
            var _tr = $("<tr>");
            var _td = {};
            for (var i = 0; i < firstDay; i++) {
                _td = $("<td>").css({ "width": 28, "text-align": "center", "line-height": "16px", "font-family": "Airal", "font-size": 14, "cursor": "pointer", "color": opt.not_current_month_date })
                .attr({ "year": pre_month.getFullYear(), "month": pre_month.getMonth() + 1 })
                .text(pre_month.getDate() - firstDay + i + 1).appendTo(_tr);
                if (isCurrentDate([_td.attr("year"), _td.attr("month"), _td.text()]))
                    _td.css({ "background": opt.selectedbg, "color": opt.selectedColor });
            }
            for (var i = firstDay; i < 7; i++) {
                _td = $("<td>").css({ "width": 28, "text-align": "center", "line-height": "16px", "font-family": "Airal", "font-size": 14, "cursor": "pointer", "color": opt.current_month_date })
                .attr({ "year": year, "month": month })
                .text(i - firstDay + 1).appendTo(_tr);
                if (isCurrentDate([_td.attr("year"), _td.attr("month"), _td.text()]))
                    _td.css({ "background": opt.selectedbg, "color": opt.selectedColor });
            }
            _table.append(_tr);
            var lc = Math.ceil((this_month.getDate() - 7 + firstDay) / 7);
            var startDay = 7 - firstDay;
            for (var i = 1; i <= lc; i++) {
                _tr = $("<tr>");
                for (var j = 1; j <= 7; j++) {
                    _td = $("<td>").css({ "width": 28, "text-align": "center", "line-height": "16px", "font-family": "Airal", "font-size": 14, "cursor": "pointer" })
                    .attr({ "year": year, "month": month }).text(++startDay).appendTo(_tr);
                    (startDay > this_month.getDate()) ?
                    _td.css("color", opt.not_current_month_date).text(startDay - this_month.getDate())
                        .attr({ "month": next_month.getMonth() + 1, "year": next_month.getFullYear() }) :
                    _td.css("color", opt.current_month_date);
                    if (isCurrentDate([_td.attr("year"), _td.attr("month"), _td.text()]))
                        _td.css({ "background": opt.selectedbg, "color": opt.selectedColor });
                }
                _table.append(_tr);
            }
            _table.find("td").each(function () {
                var oldColor = $(this).css("color");
                $(this)
                .hover(
                    function () { $(this).css({ "background": opt.hoverbg, "color": opt.hoverColor }); },
                    function () {
                        isCurrentDate([$(this).attr("year"), $(this).attr("month"), $(this).text()]) ?
                        $(this).css({ "background": opt.selectedbg, "color": oldColor }) :
                        $(this).css({ "background": opt.bg, "color": oldColor });
                    }
                )
                .click(function () {
                    obj.val($(this).attr("year") + "-" +
                    ($(this).attr("month") < 10 ? "0" : "") + $(this).attr("month") + "-" +
                    ($(this).text() < 10 ? "0" : "") + $(this).text());
                    opt.onselected();
                    setTimeout(function () { closeCalendar(); }, 200);
                });
            });

            var selects = _div.find("select");
            if (year > thisYear + opt.extend_year) {
                for (var i = opt.minYear; i <= year; i++) {
                    selects.eq(0).append("<option value='" + i + "'>" + i + "年</option>");
                    if (i == year) selects.eq(0).get(0).selectedIndex = i - opt.minYear;
                }
            }
            else {
                for (var i = opt.minYear; i <= thisYear + opt.extend_year; i++) {
                    selects.eq(0).append("<option value='" + i + "'>" + i + "年</option>");
                    if (i == year) selects.eq(0).get(0).selectedIndex = i - opt.minYear;
                }
            }
            selects.eq(0).change(function () {
                creatCalendar($(this).val() * 1, selects.eq(1).val() * 1);
                $("#calendar_single").show();
            });
            for (var i = 1; i < 13; i++) {
                selects.eq(1).append("<option value='" + i + "'>" + i + "月</option>");
                if (i === month) selects.eq(1).get(0).selectedIndex = i - 1;
            }
            selects.eq(1).change(function () {
                creatCalendar(selects.eq(0).val() * 1, $(this).val() * 1);
                $("#calendar_single").show();
            });
            if (selects.eq(0).get(0).selectedIndex === 0) {
                disabled("singleCalendarLastYear");
                if (selects.eq(1).get(0).selectedIndex === 0)
                    disabled("singleCalendarLastMonth");
            }
            if (selects.eq(0).get(0).selectedIndex === selects.eq(0).children().length - 1) {
                disabled("singleCalendarNextYear");
                if (selects.eq(1).get(0).selectedIndex === selects.eq(1).children().length - 1)
                    disabled("singleCalendarNextMonth");
            }

            var top = obj.offset().top;
            var left = obj.offset().left;
            top = $(window).height() - top < _div.height() ? top - _div.height() - 4 : top + obj.outerHeight();
            left = $(window).width() - left < _div.width() ? left - Math.abs(_div.width() - obj.width()) : left;
            _div.css({ "top": top, "left": left });
        }
        $(this.obj).click(function (e) {
            stopBubble(e);
            creatCalendar();
            $("#calendar_single").show();
        });

        function isCurrentDate(comparedObj) {
            var obj1 = [obj.val().split(opt.split)[0], obj.val().split(opt.split)[1], obj.val().split(opt.split)[2]];
            for (var i in comparedObj) {
                if (obj1[i] * 1 != comparedObj[i]) return false;
            }
            return true;
        }

        function disabled(id) {
            $("#" + id).css({ "color": opt.titleDisabledColor, "cursor": "normal" }).addClass("disabled");
        }

        function enabled(id) {
            $("#" + id).css({ "color": opt.year_month_color, "cursor": "pointer" }).removeClass("disabled");
        }

        function isDisabled(obj) {
            return $(obj).hasClass("disabled");
        }
    }
	
	function stopBubble(e){
		e = e || event;
		if (e && e.stopPropagation) e.stopPropagation();
		else window.event.cancelBubble = true;
	}
	
	function closeCalendar(){
		$("#calendar_single").hide();
	}
	
	document.onclick = function(){
		closeCalendar();
	}
	
	SingleCalendar.prototype.days = ["日","一","二","三","四","五","六"];
	window.SingleCalendar = SingleCalendar;
})(jQuery)